﻿/*
 * Copyright (c) 1995 The Regents of the University of California.
 * All rights reserved.    
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice and the following
 * two paragraphs appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.    THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

/*
 * Portions of this software Copyright (c) 1995 Brown University.
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement
 * is hereby granted, provided that the above copyright notice and the
 * following two paragraphs appear in all copies of this software.
 * 
 * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE.    THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
 * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

/*
Portions copyright (c) 2012 Eric Lasota

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


using System;
using System.Collections.Generic;
using System.Text;

namespace MPEGnet
{
    public partial class VidStream
    {
        /*
         *--------------------------------------------------------------
         *
         * DecodeMBAddrInc --
         *
         *      Huffman Decoder for macro_block_address_increment; the location
         *      in which the result will be placed is being passed as argument.
         *      The decoded value is obtained by doing a table lookup on
         *      mb_addr_inc.
         *
         * Results:
         *      The decoded value for macro_block_address_increment or ERROR
         *      for unbound values will be placed in the location specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */
        int DecodeMBAddrInc()
        {
            uint index;
            index = show_bits11();
            int val = VlcTables.mb_addr_inc[index].value;
            flush_bits(VlcTables.mb_addr_inc[index].num_bits);
            return val;
        }

        /*
         *--------------------------------------------------------------
         *
         * DecodeMotionVectors --
         *
         *      Huffman Decoder for the various motion vectors, including
         *      motion_horizontal_forward_code, motion_vertical_forward_code,
         *      motion_horizontal_backward_code, motion_vertical_backward_code.
         *      Location where the decoded result will be placed is being passed
         *      as argument. The decoded values are obtained by doing a table
         *      lookup on motion_vectors.
         *
         * Results:
         *      The decoded value for the motion vector or ERROR for unbound
         *      values will be placed in the location specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */

        int DecodeMotionVectors()
        {
            uint index;
            index = show_bits11();
            int value = VlcTables.motion_vectors[index].code;
            flush_bits(VlcTables.motion_vectors[index].num_bits);
            return value;
        }

        /*
         *--------------------------------------------------------------
         *
         * DecodeMBTypeB --
         *
         *      Huffman Decoder for macro_block_type in bidirectionally-coded
         *      pictures;locations in which the decoded results: macroblock_quant,
         *      macroblock_motion_forward, macro_block_motion_backward,
         *      macroblock_pattern, macro_block_intra, will be placed are
         *      being passed as argument. The decoded values are obtained by
         *      doing a table lookup on mb_type_B.
         *
         * Results:
         *      The various decoded values for macro_block_type in
         *      bidirectionally-coded pictures or ERROR for unbound values will
         *      be placed in the locations specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */
        void DecodeMBTypeB(out MBQuantType quant, out bool motion_fwd, out bool motion_bwd, out bool pat, out bool intra)
        {
            uint index;

            index = show_bits6();

            mb_type_entry typeEntry = VlcTables.mb_type_B[index];
            quant = (index == 0) ? MBQuantType.Error : (typeEntry.mb_quant ? MBQuantType.True : MBQuantType.False);
            motion_fwd = typeEntry.mb_motion_forward;
            motion_bwd = typeEntry.mb_motion_backward;
            pat = typeEntry.mb_pattern;
            intra = typeEntry.mb_intra;
            flush_bits(typeEntry.num_bits);
        }

        /*
         *--------------------------------------------------------------
         *
         * DecodeMBTypeI --
         *
         *      Huffman Decoder for macro_block_type in intra-coded pictures;
         *      locations in which the decoded results: macroblock_quant,
         *      macroblock_motion_forward, macro_block_motion_backward,
         *      macroblock_pattern, macro_block_intra, will be placed are
         *      being passed as argument.
         *
         * Results:
         *      The various decoded values for macro_block_type in intra-coded
         *      pictures or ERROR for unbound values will be placed in the
         *      locations specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */
        void DecodeMBTypeI(out MBQuantType quant, out bool motion_fwd, out bool motion_bwd, out bool pat, out bool intra)
        {
            uint index;
            index = show_bits2();

            motion_fwd = false;
            motion_bwd = false;
            pat = false;
            intra = true;

            if(index == 0)
                quant = MBQuantType.Error;
            else if(index == 1)
            {
                quant = MBQuantType.True;
                flush_bits(2);
            }
            else
            {
                quant = 0;
                flush_bits(1);
            }
        }

        /*
         *--------------------------------------------------------------
         *
         * DecodeMBTypeP --
         *
         *      Huffman Decoder for macro_block_type in predictive-coded pictures;
         *      locations in which the decoded results: macroblock_quant,
         *      macroblock_motion_forward, macro_block_motion_backward,
         *      macroblock_pattern, macro_block_intra, will be placed are
         *      being passed as argument. The decoded values are obtained by
         *      doing a table lookup on mb_type_P.
         *
         * Results:
         *      The various decoded values for macro_block_type in
         *      predictive-coded pictures or ERROR for unbound values will be
         *      placed in the locations specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */
        void DecodeMBTypeP(out MBQuantType quant, out bool motion_fwd, out bool motion_bwd, out bool pat, out bool intra)
        {
            uint index;

            index = show_bits6();

            mb_type_entry typeEntry = VlcTables.mb_type_P[index];
            quant = (index == 0) ? MBQuantType.Error : (typeEntry.mb_quant ? MBQuantType.True : MBQuantType.False);
            motion_fwd = typeEntry.mb_motion_forward;
            motion_bwd = typeEntry.mb_motion_backward;
            pat = typeEntry.mb_pattern;
            intra = typeEntry.mb_intra;
            flush_bits(typeEntry.num_bits);
        }

        /*
         *--------------------------------------------------------------
         *
         * DecodeCBP --
         *
         *      Huffman Decoder for coded_block_pattern; location in which the
         *      decoded result will be placed is being passed as argument. The
         *      decoded values are obtained by doing a table lookup on
         *      coded_block_pattern.
         *
         * Results:
         *      The decoded value for coded_block_pattern or ERROR for unbound
         *      values will be placed in the location specified.
         *
         * Side effects:
         *      Bit stream is irreversibly parsed.
         *
         *--------------------------------------------------------------
         */
        uint DecodeCBP()
        {
            uint index = show_bits9();
            VlcValue vlcv = VlcTables.coded_block_pattern[index];
            uint coded_bp = vlcv.value;
            flush_bits(vlcv.num_bits);
            return coded_bp;
        }
    }
}
